/*
*	Project: Aethon
*
*	File: Director.cpp
*
*	Author: Caleb Reinking
*
*	Date: 2/27/2009
*
*   Purpose: The director is the actual run class that includes int main() and
*            communicates directly with the Scene and StageHand classes
*/

#include "../include/Director.h"
#include <GL/gl.h>
#include <GL/glut.h>
#include "../include/Control.h"
#include "../include/Control2.h"
#include "../include/Timer.h"
#include <iostream>
#include <assert.h>
#include <string>

using namespace std;
	
// Constants
const unsigned int MAX_BUFFER_SIZE = 40;
const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 480;
const int DISTANCE = 20;
const int WORLD_FRAMERATE = 40;

//Scene myScene;//
Director myDirector;
bool axisLinesDesired = true;

//singleton declarations
Timer *allTheTimeWeNeed = Timer::getInstanceOf();
Control *myControl = Control::getInstanceOf();
StageHand *myStageHand = StageHand::getInstanceOf();
//StageHand *myStageHand = StageHand
int handleNumber = 1;


//Model camera;

// Function Prototypes
void display(void);
void myReshape(int w, int h);
//void initEye();
void update();//test director code, updates model velocity and direction, 
void checkHandleNumber();
//will also call collision check for physmanager
void generateNewPosition(Model& modelA);//test for velocity based movement
void worldTimer(int v);


void DrawOverlay(void);
void ViewPerspective(void);
void ViewOrtho(int x, int y);


//-------------------------------------------------------------------------	
//------------------- Methods ---------------------------------------------
//##########################################################################
void Director::run()
{
    scene.load();
    myStageHand->setScenePtr( &scene ); 
}
	
//##########################################################################
int main( int argc, char* argv[] )
{
    
    
	glutInit(&argc, argv);        
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutGameModeString("1400x1050:16@40"); glutEnterGameMode(); //[width]x[height]:[depth]@[hertz]
    //Fullscreen line above found at: http://www.opengl.org/resources/faq/technical/gettingstarted.htm#0040
    glutReshapeFunc(myReshape);
    glutDisplayFunc(display);
    glutSetCursor(GLUT_CURSOR_NONE);
    glutKeyboardFunc(Control::keyboardHandle);
    glutSpecialFunc(Control::specialHandle);
    glutPassiveMotionFunc(Control::mouseHandle);
    //createModel();//create test model for control to adjust
    //glutWarpPointer(320,240);//set pointer at center
    //#####################################
	//set control pointer values
	myControl->setHandleNumberPtr(&handleNumber);//point to
	myStageHand->setHandleNumberPtr(&handleNumber);
	glutKeyboardFunc(Control::keyboardHandle);
	glutTimerFunc(100,worldTimer,WORLD_FRAMERATE);
	myControl->setIsActive(true);//indicates that control is the active handler
//	myControl->setModelPtr(&camera);//set control pointer as camera
	myStageHand->setIsActive(false);
    //#####################################
    
    glEnable(GL_DEPTH_TEST);
    glClearDepth(1.0);
    glEnable(GL_TEXTURE_2D); 
    glClearColor(0.5, 0.5, 0.5, 1.0); // Gray
    
    //Initialization MUST take place before using display lists! otherwise no
    //display lists can be generated
    myDirector.run();
    
    glutMainLoop();
    return 0;
        
}

//int Director::getWindowHeight()
//{
//    return WINDOW_HEIGHT;
//}
//
//int Director::getWindowWidth()
//{
//    return WINDOW_WIDTH;
//}

void Director::auxDisplay()
{
     scene.display( glutGameModeGet(GLUT_GAME_MODE_HEIGHT), 
                    glutGameModeGet(GLUT_GAME_MODE_WIDTH));
}



// ######################################################################
void display(void)
{
   checkHandleNumber();
   myDirector.auxDisplay();
   myStageHand->display( WINDOW_HEIGHT, WINDOW_WIDTH ); 
   glFlush();
   glutSwapBuffers();
   
} // End display

//###################################################
void myReshape(int width, int height)
{
const int DISTANCE = 10000;
const int FOV_ANGLE = 45;

glViewport(0, 0, width, height);
Control *theControl = Control::getInstanceOf();
theControl->setSize(width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(FOV_ANGLE,  (float) width / (float) height, 1.0, DISTANCE);

cout << "New window size: " << width << " x " << height << endl;
glMatrixMode(GL_MODELVIEW);
} // End myReshape

//####################################
void checkHandleNumber()
{
	//checking to see which handler to register
	if(handleNumber==1)//should be control::handler active
	{
		if(myControl->getIsActive()==false)
		{
        glutSpecialFunc(Control::specialHandle);
		glutKeyboardFunc(Control::keyboardHandle);
		myControl->setIsActive(true);
		}//end if
	}//end if handlerNumber==1
	
	else if(handleNumber==2)//should be stagehand::handler active
	{
		if(myStageHand->getIsActive()==false)
		{
        glutSpecialFunc(StageHand::specialHandle);
		glutKeyboardFunc(StageHand::keyboardHandle);
		myStageHand->setIsActive(true);
		}//end if
	}//end if handlerNumber==2

}//end checkHandlerNumber
//####################################
void worldTimer(int v){
	glutPostRedisplay();
    allTheTimeWeNeed->incrementTime();
	glutTimerFunc(1000/WORLD_FRAMERATE,worldTimer,v);
}//end worldTimer



